package cn.sxt.userscenter.controller.head;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.sxt.userscenter.common.controller.BaseController;
import cn.sxt.userscenter.common.util.ConstatFinaUtil;
import cn.sxt.userscenter.common.util.EncryptUtil;
import cn.sxt.userscenter.common.util.PageInfoUtil;
import cn.sxt.userscenter.outer.service.IOuterService;
import cn.sxt.userscenter.users.pojo.AAdmins;
import cn.sxt.userscenter.users.pojo.AUsers;
import cn.sxt.userscenter.users.pojo.AUsersEnum;
import cn.sxt.userscenter.users.pojo.AUsersExtend;
import cn.sxt.userscenter.users.service.IUsersService;

@Controller
public class NologinController extends BaseController{
	
	@Resource
	private IUsersService usersService;
	@Resource
	private IOuterService outerService;

	/**
	 * 注册
	 * @return
	 */
	@RequestMapping("register")
	public String register(){
		ConstatFinaUtil.LOGGER.info("--register--");
		
		return "/head/register";
	}
	/**
	 * 注册提交
	 * @param request
	 * @param session
	 * @return
	 */
	@RequestMapping("/registerSubmit")
	public String registerSubmit(HttpServletRequest request,HttpSession session){
		ConstatFinaUtil.LOGGER.info("--registerSubmit--");
		String email = request.getParameter("email");
		String password = request.getParameter("password");
		String code = request.getParameter("code");
		
		/* 从session中取验证码 */
		String sessCode = session.getAttribute("rand") + "";
		
		/* 验证码从session中移除 */
		session.removeAttribute("rand");
		if(sessCode != null && sessCode.equalsIgnoreCase(code))
		{
			/* 入库 */
			AUsers users = new AUsers() ;
			users.setEmail(email);
			users.setPassword(this.encryptUtil.encode(password));
			/* 刚注册都是启用 */
			users.setStatus(AUsersEnum.STATUS_ENABLED.getStatus());
			
			users.setCreateTime(new Date());
			users.setUpdateTime(new Date());
			users.setLastLoginTime(new Date());
			
			JSONObject resultJSON = this.usersService.saveOneUsersService(users);
			this.info = resultJSON.getString("info") ; 
			if("1".equalsIgnoreCase(resultJSON.getString("code")))
			{
				/* 保存成功
				 * 发送邮件 */
				this.sendEmail(request,email);
			}
		}else
		{
			this.info = "验证码不正确" ; 
		}
		request.setAttribute("info", info);
		return this.register();
	}
	
	/**
	 * 发送邮件
	 * @param email
	 * @return
	 */
	public String sendEmail(HttpServletRequest request,String email)
	{
		Map<String, Object> condMap = new HashMap<String, Object>();
		condMap.put("email", email);
		AUsers users = this.usersService.findOneUsersService(condMap);
		if(users != null)
		{
			AUsersExtend usersExtend = users.getUsersExtend() ; 
			String subject = "尊敬的"+ email +"欢迎注册用户中心" ;
			
			/*
			 * code加密字符串:sha256(email+发送时间+uuid)
			 */
			Date date = new Date();
			String uuid = UUID.randomUUID().toString();
			String code = email + this.dateFormatUtil.formatDateTime(date) + uuid;
			code = DigestUtils.sha256Hex(code);
			
			/* 链接地址 */
			String websiteurl = ConstatFinaUtil.CONFIG_JSON.get("path.website") + "/emailverify.htm?email=" + email +"&code"+code; 
			
			/* 为生成发送邮件所需要的htlm代码,生成  */
			String fileName = "template/email_verify.html" ;
			Map<String, Object> paramsMap = new HashMap();
			paramsMap.put("subject", subject);
			paramsMap.put("email", email);
			paramsMap.put("websiteurl", websiteurl);
			paramsMap.put("date", "2017-03-28");
			String text = this.regexUtil.replaceFile(fileName, paramsMap);
			
			boolean flag = this.springEmailUtil.sendMailHTML(email, subject, text);
			
			this.info = "邮件发送,标识:" + flag ;
			/* 存储发送邮箱加密的相关信息 */
			usersExtend.setEmailSendCode(uuid);
			usersExtend.setEmailSendTime(date);
			usersExtend.setUpdateTime(new Date());
			
			/* 更新数据库 */
			this.usersService.updateOneUsersService(users);
			ConstatFinaUtil.LOGGER.info("邮箱:{},发送信息:{}",email,info);
		}else
		{
			this.info = "邮箱不存在" ; 
		}
		request.setAttribute("info", info);
		return "" ; 
	}
	
	/**
	 * 验证邮箱
	 * 
	 * ~验证时间的有效性;1天以内有效
	 * ~验证链接的合法性;code码
	 * 
	 * @return
	 */
	@RequestMapping("/emailverify")
	public String emailverify(HttpServletRequest request)
	{
		/* 接收参数 */
		String email = request.getParameter("email");
		String code = request.getParameter("code");
		
		Map<String, Object> condMap = new HashMap<String, Object>();
		condMap.put("email", email);
		AUsers users = this.usersService.findOneUsersService(condMap);
		if(users != null)
		{
			AUsersExtend usersExtend = users.getUsersExtend() ; 
			
			boolean update = true ; 
			/*~验证时间的有效性;1天以内有效*/
			Date nowDate = new Date() ; 
			if(nowDate.getTime() - usersExtend.getEmailSendTime().getTime() > 1000 * 60 * 30 )
			{
				this.info = "链接失效了"; 
				update = false ; 
			}
			
			/*~验证链接的合法性;code码
				code:加密字符串
			 * sha256(email+发送时间(yyyy-MM-dd HH:mm:ss)+uuid)
			 *  */
			String codeStr = users.getEmail() + this.dateFormatUtil.formatDateTime(usersExtend.getEmailSendTime()) + usersExtend.getEmailSendCode();
			ConstatFinaUtil.LOGGER.info("加密之前的信息:{}",codeStr);
			codeStr = DigestUtils.sha256Hex(codeStr);
			if(update && !codeStr.equalsIgnoreCase(code))
			{
				/* 链接非法 */
				this.info = "链接非法,请通过正规渠道点击" ;
				update = false ; 
			}
			
			if(update)
			{
				/* 更新邮箱验证的状态 */
				if(users.getEmailStatus() == AUsersEnum.EMAIL_STATUS_NOVERIFYED.getStatus())
				{
					/* 只有是未验证的时候再更新 */
					users.setEmailStatus(AUsersEnum.EMAIL_STATUS_VERIFYED.getStatus());
					users.setUpdateTime(new Date());
					JSONObject resultJSON = this.usersService.updateOneUsersService(users);
					this.info = resultJSON.getString("info") ;
				}else
				{
					this.info = "您已经验证过了,无法重复验证" ;
				}
			}
		}else
		{
			this.info = "邮箱不存在" ; 
		}
		request.setAttribute("info", info);
		/*ConstatFinalUtil.LOGGER.info("---信息:{}---", info);*/
		return this.info() ; 
	}
	
	
	
	
	/**
	 * 登录页面
	 * @return
	 */
	@RequestMapping("/login")
	public String login(HttpSession session){
		ConstatFinaUtil.LOGGER.info("--login--");
		session.removeAttribute("users");
		return "/head/login";
	}
	/**
	 * 登录提交
	 * @param request
	 * @param session
	 * @param id
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("/loginSubmit")
	public String loginSubmit(HttpServletRequest request,HttpServletResponse response,HttpSession session,String id) throws IOException{
		ConstatFinaUtil.LOGGER.info("--loginSubmit--");
		String email = request.getParameter("email");
		String password = request.getParameter("password");
		String code = request.getParameter("code");
		
		/* 从session中取验证码 */
		String sessCode = session.getAttribute("rand") + "";
		
		/* 验证码比对完成,从session中移除 */
		session.removeAttribute("rand");
		if(sessCode != null && sessCode.equalsIgnoreCase(code)){
			
			Map<String, Object> condMap = new HashMap<String, Object>();
			condMap.put("email", email);
			AUsers users = this.usersService.findOneUsersService(condMap);
			String info ;
			if(users != null){
				/* 邮箱存在 */
				if(this.encryptUtil.decode(password, users.getPassword())){
					/*密码正确*/
					if(users.getStatus() == AUsersEnum.STATUS_ENABLED.getStatus()){
						/* 登录成功 */
						/*放入session*/
						session.setAttribute("users", users);
						session.setAttribute("lastLoginTime", users.getLastLoginTime());
						
						/* 设置上次登录时间 */
						users.setLastLoginTime(new Date());
						this.usersService.updateOneUsersService(users);
						
						/* 判断是否有returnUrl
						 * 如果有,客户端跳转returnUrl
						 * 如果木有,直接跳转到用户中心登陆后的首页
						 *  */
						if(this.proccedReturnUrl(request,response,users))
						{
							return null; 
						}
						
						/*客户端跳转*/
						return "redirect:/head/users/main.htm";
					}else{
						/* 账户被禁用 */
						this.info = "账户被禁用";
					}
				}else{
					/* 密码错误 */
					this.info = "密码错误";
				}
				request.setAttribute("email", email);
			}else{
				/* 邮箱不存在 */
				this.info = "邮箱不存在";
			}
		}else{
			/* 验证码错误 */
			this.info = "验证码错误";
		}
		
		
		if("1".equalsIgnoreCase(id)){
			return "redirect:/head/users/main.htm";
		}
		request.setAttribute("info", this.info);
		return this.login(session);
	}
	
	/**
	 * 验证是否有returnURL
	 * @param request
	 * @param response
	 * @param users
	 * @return
	 * @throws IOException 
	 */
	private boolean proccedReturnUrl(HttpServletRequest request, HttpServletResponse response, AUsers users) throws IOException {
		/*接收returnURL*/
		String returnURL = request.getParameter("returnURL");
		/* 处理参数 */
		if(returnURL==null){
			returnURL="";
		}
		if(!"".equalsIgnoreCase(returnURL)){
			/* 在returnURL后面加上token */
			String token = UUID.randomUUID().toString();
			
			/* 为了验证token是否合法,将生成的token存储到一个地儿 
			 * 键为token:通过键可以快速的找到值
			 * 值为JSONObject:客户端需要的用户的相关信息显示到客户端的服务
			 * */
			/*  */
			JSONObject resultJSON = new JSONObject() ; 
			resultJSON.put("id", users.getId() + "");
			resultJSON.put("email", users.getEmail() + "");
			resultJSON.put("lastLoginTime", this.dateFormatUtil.formatDateTime(users.getCreateTime()));
			ConstatFinaUtil.TOKEN_MAP.put(token, resultJSON);
			
			if(returnURL.indexOf("?") != -1)
			{
				returnURL += "&token=" + token ; 
			}else
			{
				returnURL += "?token=" + token ; 
			}
			
			/*客户端跳转*/
			response.sendRedirect(returnURL);
			return true;
		}
		return false;
	}
	
	/**
	 * 验证token
	 * @param json
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/verifyToken",produces="text/html;charset=UTF-8")
	public String verifyToken(String json,HttpServletRequest request)
	{
		ConstatFinaUtil.LOGGER.info("--verifyToken--");
		long st = System.currentTimeMillis(); 
		
		JSONObject resultJSON = new JSONObject() ; 
		/*String json = request.getParameter("json");*/
		JSONObject jsonReq = new JSONObject();
		try
		{
			jsonReq = (JSONObject) JSON.parse(json);
			
			/* 版本号 */
			String version = jsonReq.get("version") + "";
			if("1".equalsIgnoreCase(version))
			{
				/* 第一个版本 */
				resultJSON = this.outerService.verifyUsersTokenService(jsonReq);
			}else
			{
				resultJSON.put("code", "6");
				resultJSON.put("info", ConstatFinaUtil.INFO_JSON.get("6"));
			}
		} catch (Exception e)
		{
			resultJSON.put("code", "4");
			resultJSON.put("info", ConstatFinaUtil.INFO_JSON.get("4"));
		}
		
		long ed = System.currentTimeMillis(); 
		
		resultJSON.put("consume", (ed - st) + "毫秒");
		return resultJSON.toJSONString() ; 
	}
	
	@RequestMapping("/adminsList")
	public String adminsList(HttpServletRequest request){
		ConstatFinaUtil.LOGGER.info("--adminsList--");
		PageInfoUtil pageInfoUtil = new PageInfoUtil() ; 
		Map<String, Object> condMap = new HashMap<String,Object>();
		List<AAdmins> adminsList = this.usersService.findListAdminsService(pageInfoUtil, condMap);
		request.setAttribute("adminsList",adminsList);
		return "/head/adminsList";
	}
	
	
	
	@RequestMapping("/aaa")
	public String aaa(){
		ConstatFinaUtil.LOGGER.info("--adminsList--");
		return "/head/aaa";
	}
}
